package com.base.cn.platform.os.controller.course.material;

import com.base.cn.platform.os.common.AdminBaseController;
import com.base.cn.platform.os.common.constants.ConfigName;
import com.base.cn.platform.os.common.log.aop.AdminModuleEnum;
import com.base.cn.platform.os.common.log.aop.OpLog;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.course.CourseType;
import com.base.cn.platform.os.common.utils.course.MaterialType;
import com.base.cn.platform.os.common.utils.file.FileDownloadUtil;
import com.base.cn.platform.os.common.utils.ke96.Ke96ServiceUtils;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.entity.course.material.CouMaterialCondition;
import com.base.cn.platform.os.service.course.cou.CourseService;
import com.base.cn.platform.os.service.course.material.CouMaterialService;
import com.base.cn.platform.os.service.course.mould.CouMouldService;
import com.base.cn.platform.os.service.manage.config.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 后台管理素材Controller
 *
 * @author s.li
 * @create 2018-04-20-9:15
 */
@Controller
@RequestMapping("/admin/course/material")
public class AdminCouMaterialController extends AdminBaseController {
    @Autowired
    private CouMaterialService couMaterialService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private CouMouldService couMouldService;
    @Autowired
    private CourseService courseService;
    @Autowired
    private Ke96ServiceUtils ke96ServiceUtils;

    /**
     * 查看素材详情
     * @param model
     * @param id 素材ID
     * @return
     */
    @RequestMapping("/showMaterialInfo")
    public String showMaterialInfo(Model model,
                                   @RequestParam("id") BigDecimal id) throws IOException{
        Map<String,Object> material = couMaterialService.findMaterialById(id,true,true);
        if(ObjectUtils.isNotEmpty(material) && ObjectUtils.isEmpty(material.get("replayUrl"))){
            material = getLiveReplayUrl(material);
        }
        model.addAttribute("material",material);
        model.addAttribute("typeList", MaterialType.values());
        return resultPage("/course/material/material_info");
    }
    /**
     * 初始化素材列表页面
     * @param model
     * @return 操作页面
     */
    @RequestMapping("/materialList")
    public String materialList(Model model){
        Map<String,Object> params = new HashMap<>();
        BigDecimal count = couMaterialService.count(params);
        model.addAttribute("count",count);
        return resultPage("/course/material/material_list");
    }

    /**
     * 获取页面列表数据
     * @param params
     * @param currentPage
     * @return
     */
    @RequestMapping("/ajaxMaterialList")
    public String ajaxMaterialList(Model model,
                                   @RequestBody Map<String,Object> params,
                                   @RequestParam(value = "currentPage",required = false,defaultValue = "1") int currentPage){
        Map<String,Object> dataMap = couMaterialService.findMaterialPage(params,currentPage,true,false);
        model.addAttribute("dataMap",dataMap);
        model.addAttribute("typeList",MaterialType.values());
        return resultPage("/course/material/material_ajax_list");
    }

    /**
     * 初始化选择素材列表页面
     * @param tag 标记
     * @param mouldId 模块ID
     * @param courseId 课程ID
     * @return 操作页面
     */
    @RequestMapping("/listMaterialType")
    public String listMaterialType(HttpServletRequest request,
                                   Model model,
                                   @RequestParam(value = "tag",required = false,defaultValue = "0") int tag,
                                   @RequestParam(value = "mouldId",required = false,defaultValue = "0") BigDecimal mouldId,
                                   @RequestParam(value = "courseId",required = false,defaultValue = "0") BigDecimal courseId){
        model.addAttribute("tag",tag);
        model.addAttribute("mouldId",mouldId);
        model.addAttribute("courseId",courseId);
        if(DataUtil.idIsNotNull(courseId)){
            Map<String,Object> course = courseService.findCourseById(courseId,false,false,false,false);
            String courseTypeKey = (String)course.get("courseTypeKey");
            if(courseTypeKey.equals(CourseType.COURSE_TYPE_LIVE.getKey())||courseTypeKey.equals(CourseType.COURSE_TYPE_SMALL.getKey())){
                return redirect(request,"/admin/course/material/initAdd?typeKey=LIVE&tag="+tag+"&mouldId=0&courseId="+courseId+"&courseTypeKey="+courseTypeKey);
            }
        }
        validateOpenCloudServices(model);
        return resultPage("/course/material/material_type");
    }

    /**
     * 初始化添加/修改素材页面
     * @param model
     * @param id 素材ID
     * @param typeKey 素材类型
     * @param tag 标记
     * @param mouldId 模块ID
     * @param courseId 课程ID
     * @return 操作页面
     */
    @RequestMapping(value = {"/initUpdate","/initAdd"})
    public String initUpdateOrAdd(Model model,
                                  @RequestParam(value = "id",required = false,defaultValue = "0") BigDecimal id,
                                  @RequestParam(value = "typeKey",required = false) String typeKey,
                                  @RequestParam(value = "tag",required = false,defaultValue = "0") int tag,
                                  @RequestParam(value = "mouldId",required = false,defaultValue = "0") BigDecimal mouldId,
                                  @RequestParam(value = "courseId",required = false,defaultValue = "0") BigDecimal courseId,
                                  @RequestParam(value = "courseTypeKey", required = false, defaultValue = "") String courseTypeKey) throws IOException {
        Map<String,Object> material = null;
        boolean flag = false;
        if(DataUtil.idIsNotNull(id)){
            material = couMaterialService.findMaterialById(id,false,true);
            if(ObjectUtils.isNotEmpty(material) && ObjectUtils.isEmpty(material.get("replayUrl"))){
                material = getLiveReplayUrl(material);
            }
            flag = true;
        }
        if(ObjectUtils.isEmpty(material)){
            material = new HashMap<>();
            material.put("typeKey",typeKey);
            if(DataUtil.idIsNotNull(mouldId)){
                material.put("mouldId",mouldId);
                Map<String,Object> couMould = couMouldService.findCouMouldById(mouldId,false,false,false);
                if(couMould!=null){
                    material.put("subjectIds",couMould.get("subjectIds"));
                }
            }
            if(DataUtil.idIsNotNull(courseId)){
                Map<String,Object> course  = courseService.findCourseById(courseId,false,false,false, false);
                if(course!=null){
                    material.put("subjectIds",course.get("subjectIds"));
                }
            }
        }
        model.addAttribute("material",material);
        model.addAttribute("tag",tag);
        //获取云服务商类型配置
        TreeMap<String,String> vlasProviderMap = sysConfigService.getSysConfigContext(ConfigName.VLASPROVIDER);
        model.addAttribute("vlasProviderMap",vlasProviderMap);
        model.addAttribute("courseTypeKey", courseTypeKey);
        if (flag) {
            return resultPage("/course/material/update_material");
        } else {
            return resultPage("/course/material/save_material");
        }
    }

    /**
     * 获取直播回放地址
     * @return
     */
    public Map<String,Object> getLiveReplayUrl(Map<String,Object> material) throws IOException{
        if(material.get("liveBilling").toString().equals("1")){//小班
            //获取小班课回放地址
            String url = "http://api.csslcloud.net/api/v2/record/info";
            Map<String, Object> params = new HashMap<>();
            params.put("roomid",material.get("roomId"));
            Map<String, Object> resultMap = ke96ServiceUtils.demandSmall(url,params);
            if(resultMap.get("result").equals("OK")){
                List<Map<String,Object>> resultList = (List<Map<String, Object>>) resultMap.get("records");
                if(ObjectUtils.isNotEmpty(resultList)){
                    String replayUrl = "";
                    for(int i=1;i<=resultList.size();i++){
                        if(ObjectUtils.isNotEmpty(resultList.get(i-1).get("replayUrl"))){
                            if(StringUtils.isNotEmpty(replayUrl)){
                                replayUrl = replayUrl + " 回放"+i+":"+resultList.get(i-1).get("replayUrl");
                            }else{
                                replayUrl = "回放"+i+":"+resultList.get(i-1).get("replayUrl");
                            }
                        }
                    }
                    material.put("replayUrl",replayUrl);
                    couMaterialService.saveMaterial(material);
                }
            }
        }else{
            //获取直播回放地址
            String url = "http://api.csslcloud.net/api/v2/record/info";
            Map<String, Object> params = new HashMap<>();
            params.put("roomid",material.get("roomId"));
            Map<String, Object> resultMap = ke96ServiceUtils.demandLive(url,params);
            if(resultMap.get("result").equals("OK")){
                List<Map<String,Object>> resultList = (List<Map<String, Object>>) resultMap.get("records");
                if(ObjectUtils.isNotEmpty(resultList)){
                    String replayUrl = "";
                    for(int i=1;i<=resultList.size();i++){
                        if(ObjectUtils.isNotEmpty(resultList.get(i-1).get("replayUrl"))){
                            if(StringUtils.isNotEmpty(replayUrl)){
                                replayUrl = replayUrl + " 回放"+i+":"+resultList.get(i-1).get("replayUrl");
                            }else{
                                replayUrl = "回放"+i+":"+resultList.get(i-1).get("replayUrl");
                            }
                        }
                    }
                    material.put("replayUrl",replayUrl);
                    couMaterialService.saveMaterial(material);
                }
            }
        }
        return material;
    }

    /**
     * 初始化
     * @param params
     * @param status 状态，2保存并发布，1保存不发布
     * @return Map<String,Object>
     */
    @RequestMapping("/saveMaterial")
    @ResponseBody
    @OpLog(module = AdminModuleEnum.COURSE,action = "保存或修改素材")
    public Map<String,Object> saveMaterial(HttpServletRequest request,
                                           @RequestBody Map<String, Object> params,
                                           @RequestParam("status") int status){
        if(status!=1 && status!=2){
            return ResultUtil.ERROR("状态错误，保存失败");
        }
        if(status==1){
            params.put("status",0);
        }else{
            params.put("status",status);
        }
        params.put("playStatus",1);//设置播放/浏览状态为正常
        params.put("createUserId",loginUtil.getLoginUserId(request));
        //如果是直播,则将直播开始结束时间差作为直播时长
        if("LIVE".equals(params.get("typeKey")) && StringUtils.isNotEmpty(params.get("videoDuration").toString())){
            Integer videoDuration = Integer.parseInt((String)params.get("videoDuration"));
            if(ObjectUtils.isEmpty(videoDuration) || videoDuration == 0){
                //2020-03-28 07:00:00
                DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                String liveBeginTimeStr = (String)params.get("liveBeginTime");
                LocalDateTime start = LocalDateTime.parse(liveBeginTimeStr, dtf);
                LocalDateTime now = LocalDateTime.now();
                String liveEndTimeStr = (String)params.get("liveEndTime");
                LocalDateTime end = LocalDateTime.parse(liveEndTimeStr, dtf);
                Duration between = Duration.between(start, end);
                params.put("videoDuration",between.getSeconds());
            }
        }

        Map<String,Object> resultMap = couMaterialService.saveMaterial(params);
        return resultMap;
    }

    /**
     * 验证素材的播放码是否存在
     * @param playUrl 播放码/直播路径/文章的音频//PC进入房间使用的唯一码
     * @param typeKey 类型，直播LIVE、视频VIDEO、文章ARTICLE,音频AUDIO
     * @return Map<String,Object>
     */
    @RequestMapping("/checkingMaterialCode")
    @ResponseBody
    public Map<String,Object> checkingMaterialCode(@RequestParam("playUrl") String playUrl,
                                                   @RequestParam("typeKey") String typeKey){
        CouMaterialCondition condition = new CouMaterialCondition();
        condition.setPlayUrl(playUrl);
        condition.setTypeKey(typeKey);
        return couMaterialService.checkingMaterialCode(condition);
    }

    /**
     * 修改素材状态（发布、取消发布、删除）
     * @param ids 素材ID串
     * @param status 状态，1取消发布，2发布，3删除
     * @return Map<String,Object>
     */
    @RequestMapping("/updateMaterialStatus")
    @ResponseBody
    @OpLog(module = AdminModuleEnum.COURSE,action = "修改素材状态")
    public Map<String,Object> updateMaterialStatus(@RequestParam("ids") String ids,@RequestParam("status") int status){
        return couMaterialService.updateMaterialStatus(ids,status);
    }

    /**
     * 修改素材浏览/播放状态
     * @param ids 素材ID串
     * @param status 状态，1正常，2冻结
     * @return Map<String,Object>
     */
    @RequestMapping("/updateMaterialPlayStatus")
    @ResponseBody
    @OpLog(module = AdminModuleEnum.COURSE,action = "修改素材浏览/播放状态")
    public Map<String,Object> updateMaterialPlayStatus(@RequestParam("ids") String ids,@RequestParam("status") int status){
        return couMaterialService.updateMaterialPlayStatus(ids,status);
    }

    /**
     * 初始化选择素材列表页面
     * @param model
     * @param type 类型，1模块选择素材，2课程选择素材
     * @return 操作页面
     */
    @RequestMapping("/selectMaterialList")
    public String selectMaterialList(Model model,
                                     @RequestParam(value = "type",required = false,defaultValue = "1") int type,
                                     @RequestParam(value = "courseId",required = false,defaultValue = "0") BigDecimal courseId,
                                     @RequestParam(value = "mouldId",required = false,defaultValue = "0") BigDecimal mouldId,
                                     @RequestParam(value = "selectType",required = false,defaultValue = "checkbox") String selectType,
                                     @RequestParam(value = "subjectIds",required = false,defaultValue = "") String subjectIds){
        model.addAttribute("selectType",selectType);
        model.addAttribute("subjectIds",subjectIds);
        model.addAttribute("type",type);
        model.addAttribute("courseId",courseId);
        model.addAttribute("mouldId",mouldId);
        Map<String,Object> course;
        if(DataUtil.idIsNotNull(courseId)){
            course = courseService.findCourseById(courseId,false,false,false,false);
        }else{
            course = new HashMap<>();
        }
        model.addAttribute("course",course);
        model.addAttribute("materialTypeList",MaterialType.values());
        return resultPage("/course/material/select_material_list");
    }

    /**
     * 获取页面列表数据
     * @param params
     * @param currentPage
     * @return
     */
    @RequestMapping("/ajaxSelectMaterialList")
    public String ajaxSelectMaterialList(Model model,
                                   @RequestBody Map<String,Object> params,
                                   @RequestParam(value = "currentPage",required = false,defaultValue = "1") int currentPage){
        Map<String,Object> dataMap = couMaterialService.findMaterialPage(params,currentPage,true,false);
        model.addAttribute("dataMap",dataMap);
        model.addAttribute("selectType",params.get("selectType"));
        model.addAttribute("materialTypeList",MaterialType.values());
        return resultPage("/course/material/select_material_ajax_list");
    }

    /**
     * 进入导入素材页面
     * @return
     */
    @RequestMapping("/import")
    public String toImportMaterial(Model model){
        validateOpenCloudServices(model);
        return resultPage("/course/material/import_material");
    }

    /**
     * 下载导入素材模板表格
     * @param materialType 素材类型，视频/音频
     * @param subjectIds 专业ID串
     * @return 返回导入模板表格
     * @throws Exception
     */
    @RequestMapping("/download")
    public ResponseEntity<byte[]> downloadMaterialTemplate(@RequestParam("materialType") String materialType,
                                                           @RequestParam("subjectIds") String subjectIds,
                                                           @RequestParam(value = "playType",required = false) String playType) throws Exception {
        return couMaterialService.downloadMaterialTemplate(materialType, subjectIds,playType);
    }

    /**
     * 执行导入素材文件
     * @param file 素材内容文件
     * @return Map<String, Object>
     */
    @RequestMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public Map<String, Object> uploadMaterial(HttpServletRequest request,
                                              @RequestPart(value = "file") MultipartFile file) {
        BigDecimal userId = loginUtil.getLoginUserId(request);
        return couMaterialService.uploadMaterial(file,userId);
    }

    /**
     * 获取元素信息素材详情
     * @param id 素材ID
     * @return
     */
    @RequestMapping("/findMaterialId")
    @ResponseBody
    public Map<String, Object> findMaterialId(@RequestParam("id") BigDecimal id){
        return   couMaterialService.findMaterialById(id,false,false);

    }

    private void  validateOpenCloudServices(Model model){
        TreeMap<String, String> sysConfigContext = sysConfigService.getSysConfigContext(ConfigName.V96K);
        TreeMap<String, String> sysConfigContextTo = sysConfigService.getSysConfigContext(ConfigName.VLASPROVIDER);
        if(!sysConfigContextTo.get("type").equals("96K")){
            model.addAttribute("isCustomerKey",true);
            model.addAttribute("isLive",true);
        }else{
            if(ObjectUtils.isNotEmpty(sysConfigContext)){
                String customerKey = sysConfigContext.get("customerKey");
                if(StringUtils.isNotEmpty(customerKey)){
                    model.addAttribute("isCustomerKey",true);
                }
                if(ObjectUtils.isNotEmpty(sysConfigContext.get("c_auth_id"))||ObjectUtils.isNotEmpty(sysConfigContext.get("p_auth_id"))||ObjectUtils.isNotEmpty(sysConfigContext.get("i_auth_id"))){
                    model.addAttribute("isLive",true);
                }
            }
        }
    }


    /**
     * 下载直播上课记录
     * @param request
     */
    @RequestMapping("/downloadExcel")
    public ResponseEntity<byte[]> downloadExcelUserLiveRecord(HttpServletRequest request,
                                                              @RequestParam("id") BigDecimal id) throws Exception{
        Map<String,Object> couMaterial =couMaterialService.findMaterialById(id,false,false);

        //表格头部
        String [] heads = new String[] {"用户ID","用户昵称","用户ip","观看时长","进入时间","离开时间","终端类型"};
        //生成文件的容器
        List<Map<String,Object>> srcFile = new ArrayList<>();
        //文件名
        String expName = couMaterial.get("name")+"上课记录";
        //获取数据
        List<Map<String,Object>>  userLiveRecordList = new ArrayList<>();
        if(couMaterial.get("liveBilling").toString().equals("1")){//互动小班直播
            userLiveRecordList = ke96ServiceUtils.smallLiveVisitData(couMaterial.get("roomId").toString(),couMaterial.get("liveBeginTime").toString(),couMaterial.get("liveEndTime").toString());
            ke96ServiceUtils.generateFile(ke96ServiceUtils.getSmallLiveData(userLiveRecordList),heads,expName+".xls",srcFile);
        }else{//并发直播
            userLiveRecordList = ke96ServiceUtils.liveVisitData(couMaterial.get("roomId").toString());
            ke96ServiceUtils.generateFile(ke96ServiceUtils.getLiveData(userLiveRecordList),heads,expName+".xls",srcFile);
        }

        return FileDownloadUtil.createRar(srcFile,expName);
    }
}
